#include "pintos_thread.h"

struct station
{
	int waitingPassenger;
	int boardingPassenger;
	int emptySeats;
	struct lock lock;
	struct condition isTrainAvailable;
	struct condition canTrainLeave;
};

void station_init(struct station *station)
{
	station->waitingPassenger = 0;
	station->boardingPassenger = 0;
	station->emptySeats = 0;
	lock_init(&station->lock);
	cond_init(&station->isTrainAvailable);
	cond_init(&station->canTrainLeave);
}

void station_load_train(struct station *station, int count)
{
	lock_acquire(&station->lock);
	// 设置火车空位个数并通知等待的乘客
	station->emptySeats = count;
	cond_broadcast(&station->isTrainAvailable, &station->lock);
	// 所有乘客都在他们的座位上，并且列车已经满员或所有等待的乘客都已经上车
	while (station->boardingPassenger != 0 || (station->emptySeats != 0 && station->waitingPassenger != 0))
	{
		cond_wait(&station->canTrainLeave, &station->lock);
	}
	station->emptySeats = 0;
	lock_release(&station->lock);
}

void station_wait_for_train(struct station *station)
{
	lock_acquire(&station->lock);
	// 等待的乘客增加
	station->waitingPassenger++;
	// 若火车空位不够则继续等待
	while (station->boardingPassenger >= station->emptySeats)
	{
		cond_wait(&station->isTrainAvailable, &station->lock);
	}
	station->waitingPassenger--;
	station->boardingPassenger++;
	lock_release(&station->lock);
}

void station_on_board(struct station *station)
{
	lock_acquire(&station->lock);
	station->boardingPassenger--;
	station->emptySeats--;
	cond_signal(&station->canTrainLeave, &station->lock);
	lock_release(&station->lock);
}
